package jp.wug.core;

import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.Scope;
import jp.wug.WugConversation;
import jp.wug.WugRequest;

public class ConversationScope implements Scope {
    private Provider<WugRequest> requestProvider = new Provider<WugRequest>() {
        public WugRequest get() {
            throw new AssertionError("ConversationScope not initialized properly");
        }
    };

    public void setRequestProvider(Provider<WugRequest> requestProvider) {
        this.requestProvider = requestProvider;
    }

    public <T> Provider<T> scope(Key<T> key, Provider<T> provider) {
        return new ProviderImpl<T>(key, provider);
    }

    private class ProviderImpl<T> implements Provider<T> {
        private final Key<T> key;
        private final Provider<T> provider;

        ProviderImpl(Key<T> key, Provider<T> provider) {
            this.key = key;
            this.provider = provider;
        }

        public T get() {
            WugConversation conversation = requestProvider.get().getConversation();
            if (conversation.containsKey(key)) {
                return conversation.get(key);
            } else {
                T t = provider.get();
                conversation.put(key, t);
                return t;
            }
        }

        public String toString() {
            return String.format("%s[%s]", provider, ConversationScope.this);
        }
    }
}
